// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CloudQueueMessage.cs" company="AzureContrib (Open source library http://azurecontrib.codeplex.com)">
//   Microsoft Public License (Ms-PL)
// </copyright>
// <summary>
//   Wrapper around <see cref="Microsoft.WindowsAzure.StorageClient.CloudQueueMessage" />
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.Collections.ObjectModel;
using System.Linq;

using Microsoft.WindowsAzure.StorageClient;

namespace AzureContrib.WindowsAzure.StorageClient
{
	/// <summary>
	/// Wrapper around <see cref="Microsoft.WindowsAzure.StorageClient.CloudQueueMessage"/>
	/// </summary>
	/// <typeparam name="T">The type of payload</typeparam>
	public class CloudQueueMessage<T>
	{
		private readonly Microsoft.WindowsAzure.StorageClient.CloudQueueMessage cloudQueueMessage;

		/// <summary>
		/// Initializes a new instance of the <see cref="CloudQueueMessage{T}"/> class. 
		/// Create a typed <see cref="Microsoft.WindowsAzure.StorageClient.CloudQueueMessage"/> that exposes a deserialized payload
		/// </summary>
		/// <param name="cloudQueueMessage">The original <see cref="cloudQueueMessage"/>.</param>
		public CloudQueueMessage(Microsoft.WindowsAzure.StorageClient.CloudQueueMessage cloudQueueMessage)
		{
			this.cloudQueueMessage = cloudQueueMessage;
		}

		/// <summary>
		/// Gets the wrapped <see cref="Microsoft.WindowsAzure.StorageClient.CloudQueueMessage.AsBytes"/>
		/// </summary>
		public ReadOnlyCollection<byte> AsBytes
		{
			get
			{
				return cloudQueueMessage.AsBytes.ToList().AsReadOnly();
			}
		}

		/// <summary>
		/// Gets the wrapped <see cref="Microsoft.WindowsAzure.StorageClient.CloudQueueMessage.Id"/>
		/// </summary>
		public string Id
		{
			get
			{
				return cloudQueueMessage.Id;
			}
		}

		/// <summary>
		/// Gets the wrapped <see cref="Microsoft.WindowsAzure.StorageClient.CloudQueueMessage.PopReceipt"/>
		/// </summary>
		public string PopReceipt
		{
			get
			{
				return cloudQueueMessage.PopReceipt;
			}
		}

		/// <summary>
		/// Gets the wrapped <see cref="Microsoft.WindowsAzure.StorageClient.CloudQueueMessage.InsertionTime"/>
		/// </summary>
		public DateTime? InsertionTime
		{
			get
			{
				return cloudQueueMessage.InsertionTime;
			}
		}

		/// <summary>
		/// Gets the wrapped <see cref="Microsoft.WindowsAzure.StorageClient.CloudQueueMessage.ExpirationTime"/>
		/// </summary>
		public DateTime? ExpirationTime
		{
			get
			{
				return cloudQueueMessage.ExpirationTime;
			}
		}

		/// <summary>
		/// Gets the wrapped <see cref="Microsoft.WindowsAzure.StorageClient.CloudQueueMessage.NextVisibleTime"/>
		/// </summary>
		public DateTime? NextVisibleTime
		{
			get
			{
				return cloudQueueMessage.NextVisibleTime;
			}
		}

		/// <summary>
		/// Gets the wrapped <see cref="Microsoft.WindowsAzure.StorageClient.CloudQueueMessage.AsString"/>
		/// </summary>
		public string AsString
		{
			get
			{
				return cloudQueueMessage.AsString;
			}
		}

		/// <summary>
		/// Gets the wrapped <see cref="Microsoft.WindowsAzure.StorageClient.CloudQueueMessage.DequeueCount"/>
		/// </summary>
		public int DequeueCount
		{
			get
			{
				return cloudQueueMessage.DequeueCount;
			}
		}

		/// <summary>
		/// <see cref="CloudQueueMessage{T}"/> is actually wrapping up a <see cref="Microsoft.WindowsAzure.StorageClient.CloudQueueMessage"/>
		/// </summary>
		/// <param name="cloudQueueMessage">The <see cref="CloudQueueMessage{T}"/></param>
		/// <returns>The <see cref="Microsoft.WindowsAzure.StorageClient.CloudQueueMessage"/> wrapped up inside.</returns>
		public static implicit operator CloudQueueMessage(CloudQueueMessage<T> cloudQueueMessage)
		{
			return cloudQueueMessage != null ? cloudQueueMessage.cloudQueueMessage : null;
		}

		/// <summary>
		/// <see cref="CloudQueueMessage{T}"/> is actually wrapping up a <see cref="Microsoft.WindowsAzure.StorageClient.CloudQueueMessage"/>
		/// </summary>
		/// <param name="cloudQueueMessage">The <see cref="CloudQueueMessage{T}"/></param>
		/// <returns>The <see cref="Microsoft.WindowsAzure.StorageClient.CloudQueueMessage"/> wrapped up inside.</returns>
		public static implicit operator CloudQueueMessage<T>(CloudQueueMessage cloudQueueMessage)
		{
			return new CloudQueueMessage<T>(cloudQueueMessage);
		}

		/// <summary>
		/// Make this instance into a <see cref="CloudQueueMessage"/>.
		/// </summary>
		/// <returns>A <see cref="CloudQueueMessage"/>.</returns>
		public CloudQueueMessage ToCloudQueueMessage()
		{
			return this;
		}

		/// <summary>
		/// The body of this instance deserialized from JSON to an instance of <typeparamref name="T"/>.
		/// </summary>
		/// <returns>The instance.</returns>
		public T Payload()
		{
			return CloudQueueMessageExtensions.Payload<T>(this);
		}
	}
}